package com.free.semantic.core.script.impl;

import com.alibaba.fastjson.JSON;
import com.free.semantic.common.*;
import com.free.semantic.core.ConceptInstanceManage;
import com.free.semantic.core.ConceptManage;
import com.free.semantic.core.RelationFunction;
import com.free.semantic.core.adaptor.impl.ModelAdaptorImpl;
import com.free.semantic.core.impl.ConceptInstanceManageImpl;
import com.free.semantic.core.impl.ConceptManageImpl;
import com.free.semantic.core.script.SemanticNetEngine;
import com.free.semantic.core.takeclient.ConceptInsTakeCommand;
import com.free.semantic.exception.EndOfFileException;
import com.free.semantic.req.RelaItemDef;
import com.free.semantic.utils.Utils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiConsumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.free.semantic.common.RangeObj.one;
import static com.free.semantic.core.concept.impl.ConceptSelfInfoConcept.*;

public class ScriptEngineImpl implements SemanticNetEngine {

    @Override
    public ConceptManage buildConceptFromScript(String script) {
        ConceptManage conceptManage = new ConceptManageImpl();
        execScript(script, conceptManage);
        return conceptManage;
    }

    /**
     * todo 这个代码没有完美的将原始的语义网络复刻下来，有优化空间，并且针对重复名称对象的复制也有问题
     *
     * @param conceptInsTakeCommand
     * @return
     */
    @Override
    public ConceptManage buildManageFromTake(ConceptInsTakeCommand conceptInsTakeCommand) {
        ConceptManage conceptManage = new ConceptManageImpl();
        Utils.mergerConcept(conceptManage, conceptInsTakeCommand);
        return conceptManage;
    }

    private static Object take(ConceptInstanceManage conceptManage, String input) {
// 主正则表达式，匹配整体结构
        Pattern mainPattern = Pattern.compile("^take\\s*(.*?)\\s*,\\s*([^)]+?)\\s*$");
        Matcher matcher = mainPattern.matcher(input);
        if (!matcher.matches()) {
            throw new RuntimeException("格式不正确");
        }
        String nodesPart = matcher.group(1).trim();
        String dest = matcher.group(2).trim();

        // 匹配所有括号项（如 (node,value)）
        Pattern entryPattern = Pattern.compile("\\(([^)]+)\\)");
        Matcher entryMatcher = entryPattern.matcher(nodesPart);
        List<BaseNode> nodes = new ArrayList<>();
        while (entryMatcher.find()) {
            String entryContent = entryMatcher.group(1).trim(); // 获取括号内的内容
            String[] parts = entryContent.split("\\s*,\\s*", 2); // 分割 node 和 value
            if (parts.length > 2 || parts.length < 1) {
                throw new RuntimeException("无效的括号项内容: " + entryContent);
            }
            if (parts.length == 2) {
                String node = parts[0].trim();
                String value = parts[1].trim();
                nodes.add(new ParamNode(node, value));
            }
            if (parts.length == 1) {
                String node = parts[0].trim();
                nodes.add(new LocatorNode(node));
            }
        }
        return conceptManage.goByLocatorNode(nodes, RangeObj.parse(dest));
    }


    @Override
    public void execScript(ConceptManage conceptManage, String script) {
        execScript(script, conceptManage);
    }

    @Override
    public ConceptInstanceManage execScript(ConceptManage target, String formulas, ConceptInstanceManage instanceManage) {
        //return execScript1(target, formulas, instanceManage);
        return execScript2(target, formulas, instanceManage);
    }

    private ConceptInstanceManage execScript2(ConceptManage target, String formulas, ConceptInstanceManage instanceManage) {

        ConceptInstanceManage emptyImpl = new ConceptInstanceManageImpl(target);
        execScript(instanceManage, formulas);
        ModelAdaptorImpl modelAdaptor = new ModelAdaptorImpl();

        modelAdaptor.setInterfaceModel(emptyImpl);
        modelAdaptor.setImplementModel(instanceManage);

        List<EqualFormula> equalFormulas = convertToFormula("target", "default", formulas);

        for (EqualFormula equalFormula : equalFormulas) {
            modelAdaptor.addEqualFormula(equalFormula);
        }
        emptyImpl.registerFunction("test", modelAdaptor.build());
        return emptyImpl;
    }


    private List<EqualFormula> convertToFormula(String left, String right, String formulas) {
        List<EqualFormula> result = new ArrayList<>();
        String[] allLine = formulas.split("\n");
        for (String s : allLine) {
            String[] split = s.split("//");
            String trim = split[0].trim();
            if (StringUtils.isBlank(trim) || !trim.startsWith("eq ")) {
                continue;
            }
            trim = trim.substring(2).trim();
            if (StringUtils.isBlank(trim)) {
                continue;
            }
            EqualFormula formula = EqualFormula.parse(left, right, trim);
            result.add(formula);
        }
        return result;
    }

    public static Map<String, String> parseFormulaMap(String formulas) {
        Map<String, String> result = new HashMap<>();
        String[] allLine = formulas.split("\n");
        for (String s : allLine) {
            String[] split = s.split("//");
            String trim = split[0].trim();
            if (StringUtils.isBlank(trim) || !trim.startsWith("eq ")) {
                continue;
            }
            trim = trim.substring(2).trim();
            if (StringUtils.isBlank(trim)) {
                continue;
            }
            EqualFormula formula = EqualFormula.parse("", "", trim);
            result.put(formula.getRightObjectName(), formula.getLeftObjectName());
        }
        return result;
    }

    @Override
    public Object execScript(ConceptInstanceManage conceptManage, String script) {
        return execScript(script, conceptManage);
    }

    private static Object hideObject(ConceptInstanceManage manage, String input) {
        FuncCall funcCall = readFuncCallIgnore(input);
        String[] objectList = funcCall.paramExpress.split(",");
        manage.hideObject(Ls.of(objectList));
        return "success";
    }

    private static Object removeItem(ConceptInstanceManage manage, String input) {
        FuncCall funcCall = readFuncCallIgnore(input);
        String[] objectList = funcCall.paramExpress.split(",");
        if (objectList.length < 2) {
            throw new RuntimeException(String.format("表达式%s参数数量有误", input));
        }
        List<String> params = Arrays.stream(objectList).collect(Collectors.toList());
        manage.concept().removeRelationItem(params.subList(0, params.size() - 1),
                params.get(params.size() - 1));
        return "success";
    }

    private static Object removeObject(ConceptInstanceManage manage, String input) {
        FuncCall funcCall = readFuncCallIgnore(input);
        String[] objectList = funcCall.paramExpress.split(",");
        List<String> params = Arrays.stream(objectList).collect(Collectors.toList());
        manage.concept().removeObject(params);
        return "success";
    }

    private void execScript(String script, ConceptManage conceptManage) {
        ScriptReader reader = new ScriptReader(script);

        Map<String, RelationParamLsInfo> relationParamLsInfoMap = new HashMap<>();

        while (reader.hasNext()) {

            String line = reader.nextLine();
            if (line.startsWith("//") || StringUtils.isBlank(line)) {
                continue;
            }
            if (line.startsWith("object ")) {
                createObj(conceptManage, line);
                continue;
            }
            if (line.startsWith("relation ")) {
                RelationParamLsInfo relationDef = createRelationDef(conceptManage, reader, line);
                relationParamLsInfoMap.put(relationDef.getRelationName(), relationDef);
                continue;
            }
            createRelationInstance(conceptManage, line);
        }
    }

    /**
     * 1. 实现的注册必须通过take函数进行
     * 2. 抽象一些基本的语义网络用于管理 语义网络本身
     * 3. 我需要抽象一个新的接口
     * 4. 并且可以利用即将要开发的功能，语义网络扩展实现
     * 5. 所以这些能力只要语义网络实现一个扩展语义网络的接口就可以了
     *
     * @param conceptInsTakeCommand
     * @return
     */
    @Override
    public ConceptInstanceManage buildManageInsFromTake(ConceptInsTakeCommand conceptInsTakeCommand) {
        ConceptManage conceptManage = new ConceptManageImpl();
        Utils.mergerConcept(conceptManage, conceptInsTakeCommand);

        ConceptInstanceManage instanceManage = new ConceptInstanceManageImpl(conceptManage);

        Utils.forEachRelationItem(conceptManage, relationItem -> {
            RelationFunction function = instanceManage.getFunction(relationItem.getSourceObjectList(), relationItem.getDestObject());
            if (function != null) {
                return;
            }
            List<Object> result = conceptInsTakeCommand.take(Ls.of(new ParamNode(SOURCE, relationItem.getSourceObjList()),
                    new ParamNode(DEST, relationItem.getDestObj())), one(HAS_IMPLEMENT));
            if (CollectionUtils.isEmpty(result) || result.isEmpty()) {
                throw new RuntimeException(String.format("查询关系%s是否具有实现", relationItem));
            }
            boolean hasImplement = Boolean.parseBoolean(result.get(0).toString());
            if (hasImplement) {
                instanceManage.registerFunction(relationItem.getSourceObjList(), relationItem.getDestObj(), context -> {
                    List<BaseNode> paramNodes = new ArrayList<>();
                    for (String s : relationItem.getSourceObjList()) {
                        paramNodes.add(new ParamNode(s, context.getListValue(s)));
                    }
                    List<Object> value = conceptInsTakeCommand.take(paramNodes, relationItem.getDestObject());
                    context.setValue(relationItem.getDestObj(), value);
                });
            }
        });
        return instanceManage;
    }

    private static Map<String, BiConsumer<ConceptInstanceManage, List<String>>> solvers = new ConcurrentHashMap<>();

    private Object execScript(String script, ConceptInstanceManage conceptManage) {
        ScriptReader reader = new ScriptReader(script);
        Object lastResult = true;
        while (reader.hasNext()) {

            String line = reader.nextLine();
            if (line.startsWith("//") || StringUtils.isBlank(line)) {
                continue;
            }
            if (line.startsWith("object ")) {
                createObj(conceptManage.concept(), line);
                lastResult = true;
                continue;
            }
            // take((node1,value),(node2,value),(node3,value),dest)
            if (line.startsWith("take")) {
                lastResult = take(conceptManage, line);
                continue;
            }
            //buildMap((node1,value),((node2,value),(node3,value)));
            if (line.startsWith("buildMap")) {
                lastResult = buildMap(conceptManage, line);
                continue;
            }
            //buildConstMap((sourceObj,destObj),constValue)
            if (line.startsWith("buildConstMap")) {
                lastResult = buildConstMap(conceptManage, line);
                continue;
            }
            //buildEqualMap((sourceAObj,sourceBObj,destObj),sourceBObj)
            if (line.startsWith("buildEqualMap")) {
                lastResult = buildEqualMap(conceptManage, line);
                continue;
            }
            if (line.startsWith("eq ")) {
                continue;
            }
            // conceptMerge((fromSource1,fromSource2...fromDest),(toSource1,toSource2...toDest))
            if (line.startsWith("conceptMerge")) {
                lastResult = conceptMerge(conceptManage.concept(), line);
                continue;
            }
            // addObjBwRelation((source1,source2...dest),(middleObj1,middleObj2...))
            if (line.startsWith("addObjBwRelation")) {
                lastResult = addObjBetweenRelation(conceptManage.concept(), line);
                continue;
            }
            // hideObject(objectName...)
            if (line.startsWith("hideObject")) {
                lastResult = hideObject(conceptManage, line);
                continue;
            }
            if (line.startsWith("removeItem")) {
                lastResult = removeItem(conceptManage, line);
                continue;
            }
            if (line.startsWith("removeObject")) {
                lastResult = removeObject(conceptManage, line);
                continue;
            }
            if (line.startsWith("relation ")) {
                createRelationDef(conceptManage.concept(), reader, line);
                lastResult = true;
                continue;
            }

            if (line.startsWith("script ")) {
                List<String> collect = Arrays.stream(line.split(" ")).filter(aa -> !aa.isEmpty()).collect(Collectors.toList());
                if (collect.size() != 3) {
                    throw new RuntimeException(String.format("表达式%s有误，必须是 script {solver} begin", line));
                }
                if (!solvers.containsKey(collect.get(1))) {
                    throw new RuntimeException(String.format("表达式%s有误，必须是 script {solver} begin", line));
                }
                if (!"begin".equalsIgnoreCase(collect.get(2))) {
                    throw new RuntimeException(String.format("表达式%s有误，必须是 script {solver} begin", line));
                }
                List<String> scriptLs = new ArrayList<>();
                while (reader.hasNext()) {
                    String nextLine = reader.nextLine();
                    if (nextLine.startsWith("//") || StringUtils.isBlank(nextLine)) {
                        continue;
                    }
                    if (nextLine.startsWith("end")) {
                        break;
                    }
                    scriptLs.add(nextLine);
                }
                solvers.get(collect.get(1)).accept(conceptManage, scriptLs);
                continue;
            }
            createRelationInstance(conceptManage.concept(), line);
            lastResult = true;
        }
        return JSON.toJSONString(lastResult);
    }

    public static void registerScriptSolver(String sourceName, BiConsumer<ConceptInstanceManage, List<String>> solver) {
        synchronized (solvers) {
            if (!solvers.containsKey(sourceName)) {
                solvers.put(sourceName, solver);
            } else {
                throw new RuntimeException(String.format("脚本解析器%s已经存在", sourceName));
            }
        }
    }


    private static Object addObjBetweenRelation(ConceptManage manage, String input) {
        FuncCall funcCall = readFuncCallIgnore(input);
        ReadContext fromAll = readBracket(funcCall.paramExpress);
        ReadContext comma = readComma(fromAll.leftString);

        ReadContext middleObj = readBracketIgnore(comma.leftString);

        List<String> fromAllObj = new ArrayList<>();
        List<RangeObj> middleObjLs = splitRangeObjStr(middleObj.express);
        for (String obj : fromAll.express.split(",")) {
            fromAllObj.add(obj.trim());
        }
        if (fromAllObj.size() != 2) {
            throw new IllegalArgumentException(String.format("表达式%s有误，仅支持来源事物为一个的关系", input));
        }
        manage.addObjectBetweenRelationItem(fromAllObj.get(0), fromAllObj.get(1), middleObjLs);
        return "success";
    }

    private static List<RangeObj> splitRangeObjStr(String rangeObjStr) {
        List<String> result = new ArrayList<>();

        int lastCommaIndex = 0;
        int stackLength = 0;

        for (int i = 0; i < rangeObjStr.length(); i++) {
            char charAt = rangeObjStr.charAt(i);
            if (charAt == '(' || charAt == '[') {
                stackLength++;
            }
            if (charAt == ')' || charAt == ']') {
                stackLength--;
            }
            if (charAt == ',' && stackLength == 0) {
                result.add(rangeObjStr.substring(lastCommaIndex, i).trim());
                lastCommaIndex = i + 1;
            }
        }
        result.add(rangeObjStr.substring(lastCommaIndex, rangeObjStr.length()).trim());
        return result.stream().map(RangeObj::parse).collect(Collectors.toList());
    }


    // conceptMerge((fromSource1,fromSource2,,,fromDest),(toSource1,toSource2,,,toDest))
    private static Object conceptMerge(ConceptManage manage, String input) {
        FuncCall funcCall = readFuncCall(input);
        ReadContext fromAll = readBracket(funcCall.paramExpress);
        ReadContext comma = readComma(fromAll.leftString);

        ReadContext toAll = readBracket(comma.leftString);

        List<String> fromAllObj = new ArrayList<>();
        List<String> toAllObj = new ArrayList<>();

        for (String obj : fromAll.express.split(",")) {
            fromAllObj.add(obj.trim());
        }
        for (String obj : toAll.express.split(",")) {
            toAllObj.add(obj.trim());
        }
        if (fromAllObj.size() < 2 || toAllObj.size() < 2) {
            throw new IllegalArgumentException(String.format("表达式%s有误", input));
        }
        manage.conceptMergeTo(fromAllObj.subList(0, fromAllObj.size() - 1), fromAllObj.get(fromAllObj.size() - 1),
                toAllObj.subList(0, toAllObj.size() - 1), toAllObj.get(toAllObj.size() - 1));

        return "success";
    }


    //buildMap((node1,value),(node2,value),(node3,value));
    private static Object buildMap(ConceptInstanceManage conceptManage, String input) {
        // 主正则表达式，匹配整体结构
        FuncCall funcCall = readFuncCall(input);
        ReadContext bracket = readBracket(funcCall.paramExpress);
        Pair sourceAndDest = readPair(bracket.express);
        ReadContext comma = readComma(bracket.leftString);
        List<Pair> leftPair = new ArrayList<>();
        ReadContext bracketC = readBracket(comma.leftString);
        while (StringUtils.isNotBlank(bracketC.leftString)) {
            leftPair.add(readPair(bracketC.express));
            ReadContext comma1 = readComma(bracketC.leftString);
            bracketC = readBracket(comma1.leftString);
        }
        leftPair.add(readPair(bracketC.express));

        String[][] array = new String[leftPair.size()][sourceAndDest.key.length + 1];

        for (int i = 0; i < leftPair.size(); i++) {
            Pair pair = leftPair.get(i);
            String[] kv = new String[sourceAndDest.key.length + 1];
            System.arraycopy(pair.key, 0, kv, 0, pair.key.length);
            kv[sourceAndDest.key.length] = pair.value;
            array[i] = kv;
        }
        conceptManage.registerFunction(Ls.of(sourceAndDest.key), sourceAndDest.value,
                Utils.buildFunc(sourceAndDest.key, sourceAndDest.value, array));
        return true;
    }

    //buildEqualMap((sourceAObj,sourceBObj,destObj),sourceBObj)
    private static Object buildEqualMap(ConceptInstanceManage conceptManage, String input) {
        FuncCall funcCall = readFuncCall(input);
        ReadContext bracket = readBracket(funcCall.paramExpress);
        Pair sourceAndDest = readPair(bracket.express);
        ReadContext comma = readComma(bracket.leftString);

        String valueObject = comma.leftString;
        List<String> sourceObjList = Ls.of(sourceAndDest.key);
        if (!sourceObjList.contains(valueObject)) {
            throw new IllegalArgumentException(String.format("表达式%s有误，值对象不存在于来源事物中", input));
        }
        Utils.registerTheSameFunction(conceptManage, sourceObjList, sourceAndDest.value, valueObject);
        return true;
    }

    //buildConstMap((sourceObj,destObj),constValue)
    private static Object buildConstMap(ConceptInstanceManage conceptManage, String input) {
        FuncCall funcCall = readFuncCall(input);
        ReadContext bracket = readBracket(funcCall.paramExpress);
        Pair sourceAndDest = readPair(bracket.express);
        ReadContext comma = readComma(bracket.leftString);
        String constValue = comma.leftString;
        Utils.registerConstFunction(conceptManage, Ls.of(sourceAndDest.key), sourceAndDest.value, constValue);
        return true;
    }

    public static class FuncCall {

        private String funcName;

        private String paramExpress;

    }

    private static FuncCall readFuncCall(String input) {
        FuncCall funcCall = new FuncCall();
        ReadContext funcName = readFuncName(input);
        ReadContext bracket = readBracket(funcName.leftString);
        assert StringUtils.isBlank(bracket.leftString);
        funcCall.funcName = funcName.express;
        funcCall.paramExpress = bracket.express;
        return funcCall;
    }

    private static FuncCall readFuncCallIgnore(String input) {
        FuncCall funcCall = new FuncCall();
        ReadContext funcName = readFuncName(input);
        ReadContext bracket = readBracketIgnore(funcName.leftString);
        assert StringUtils.isBlank(bracket.leftString);
        funcCall.funcName = funcName.express;
        funcCall.paramExpress = bracket.express;
        return funcCall;
    }


    public static class ReadContext {
        public String express;
        public String leftString;
    }

    private static ReadContext readFuncName(String input) {
        if (StringUtils.isBlank(input)) {
            throw new RuntimeException("表达式为空");
        }
        ReadContext context = new ReadContext();
        int index = input.indexOf("(");
        context.express = input.substring(0, index).trim();
        context.leftString = input.substring(index);
        return context;
    }

    private static ReadContext readComma(String input) {
        if (StringUtils.isBlank(input)) {
            throw new RuntimeException("表达式为空");
        }
        String trim = input.trim();
        if (!trim.startsWith(",")) {
            throw new RuntimeException(String.format("表达式%s缺少,", input));
        }
        ReadContext context = new ReadContext();
        context.express = ",";
        context.leftString = input.substring(1);
        return context;
    }

    public static class Pair {
        String[] key;
        String value;
    }

    private static Pair readPair(String input) {
        Pair pair = new Pair();
        String[] split = input.split(",");
        assert split.length >= 2;
        pair.key = Arrays.stream(split).collect(Collectors.toList()).subList(0, split.length - 1).toArray(new String[split.length - 1]);
        pair.value = split[split.length - 1].trim();
        return pair;
    }

    private static ReadContext readBracket(String input) {
        String trim = input.trim();
        if (StringUtils.isBlank(input)) {
            throw new RuntimeException("表达式为空");
        }
        if (!trim.startsWith("(")) {
            throw new RuntimeException(String.format("表达式%s缺少(", input));
        }
        ReadContext context = new ReadContext();
        int count = 0;
        int endIndex = 0;
        for (int i = 1; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '(') {
                count++;
                continue;
            }
            if (c == ')') {
                if (count == 0) {
                    endIndex = i;
                    break;
                }
                count--;
            }
        }
        if (endIndex == 0) {
            throw new RuntimeException(String.format("表达式%s缺少(", input));
        }
        context.express = input.substring(1, endIndex);
        context.leftString = input.substring(endIndex + 1);
        return context;
    }

    private static ReadContext readBracketIgnore(String input) {
        String trim = input.trim();
        if (StringUtils.isBlank(input)) {
            throw new RuntimeException("表达式为空");
        }
        if (!trim.startsWith("(")) {
            throw new RuntimeException(String.format("表达式%s缺少(", input));
        }
        ReadContext context = new ReadContext();
        int count = 0;
        int endIndex = 0;
        for (int i = 1; i < input.length(); i++) {
            char c = input.charAt(i);
            if (c == '(' || c == '[') {
                count++;
                continue;
            }
            if (c == ')' || c == ']') {
                if (count == 0) {
                    endIndex = i;
                    break;
                }
                count--;
            }
        }
        if (endIndex == 0) {
            throw new RuntimeException(String.format("表达式%s缺少(", input));
        }
        context.express = input.substring(1, endIndex);
        context.leftString = input.substring(endIndex + 1);
        return context;
    }


    private void createObj(ConceptManage conceptManage, String line) {
        String substring = line.substring("object ".length());
        String[] allObject = split(substring);
        for (String name : allObject) {
            if (StringUtils.isBlank(name)) {
                continue;
            }
            conceptManage.addConcept(name);
        }
    }

    private RelationParamLsInfo createRelationDef(ConceptManage conceptManage, ScriptReader reader, String line) {
        String regex = "^relation\\s+(\\S+)\\(([A-Z,]+)\\)$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(line);

        if (matcher.matches()) {
            // 提取字符串
            String relationName = matcher.group(1);

            RelationParamLsInfo paramLsInfo = new RelationParamLsInfo();

            // 提取变量列表
            String variableStr = matcher.group(2);
            String[] variables = variableStr.split(",");
            List<String> variableList = new ArrayList<>(Arrays.asList(variables));

            paramLsInfo.setParamList(variableList);
            paramLsInfo.setRelationName(relationName);

            List<RelaItemDef> relaItemDefLs = new ArrayList<>();

            while (reader.hasNext()) {
                String line1 = reader.nextLine();
                String itemDescription = removeComment(line1);
                if (StringUtils.isBlank(itemDescription)) {
                    continue;
                }
                RelaItemDef relaItemDef = readeRelationItem(itemDescription);
                if (relaItemDef == null) {
                    reader.goBack();
                    break;
                } else {
                    relaItemDefLs.add(relaItemDef);
                }
            }
            conceptManage.addRelationDefine(relationName, relaItemDefLs);
            return paramLsInfo;
        } else {
            throw new RuntimeException("");
        }
    }

    private static class RelationParamLsInfo {

        private String relationName;

        private List<String> paramList;

        public String getRelationName() {
            return relationName;
        }

        public void setRelationName(String relationName) {
            this.relationName = relationName;
        }

        public List<String> getParamList() {
            return paramList;
        }

        public void setParamList(List<String> paramList) {
            this.paramList = paramList;
        }
    }

    private RelaItemDef readeRelationItem(String line) {
        String[] relation = line.split("->");
        if (relation.length != 2) {
            return null;
        }
        String leftPart = relation[0];
        String itemName = null;
        List<RangeObj> allSource = new ArrayList<>();

        String reqSourceStr = leftPart;

        if (leftPart.contains(":")) {
            String[] split = leftPart.split(":");

            if (split.length != 2) {
                throw new RuntimeException(" 关系项定义错误");
            }
            itemName = split[0];
            reqSourceStr = removeBracket(split[1]);
        }
        String[] allReq = split(removeBracket(reqSourceStr));
        for (int i = 0; i < allReq.length; i++) {
            RangeObj rangeObj = convertToRangeObj(allReq[i]);
            allSource.add(rangeObj);
        }

        String rightPart = relation[1];
        RangeObj destObj = convertToRangeObj(rightPart);
        RelaItemDef itemDef = new RelaItemDef(allSource, destObj);

        itemDef.setName(itemName);
        itemDef.setSourceObjectList(allSource);
        itemDef.setDestObject(destObj);
        return itemDef;
    }

    private String removeBracket(String express) {
        if (express.startsWith("(") && express.endsWith(")")) {
            return express.substring(1, express.length() - 1);
        }
        return express;
    }

    public static RangeObj convertToRangeObj(String express) {
        if (express.contains("=")) {
            String[] split = express.split("=");
            if (split.length != 2) {
                throw new RuntimeException(String.format("%s 表达式有误", express));
            }
            String variable = split[0];
            if (isValidString(variable)) {
                RangeObj rangeObj = new RangeObj();
                rangeObj.setRange(parseRange(split[1]));
                rangeObj.setObjectName(variable);
                return rangeObj;
            } else {
                throw new RuntimeException(String.format("表达式 %s有误", express));
            }
        }
        Range range = Range.ONE;
        int startIndex = 0;
        if (express.contains(")")) {
            int index = express.lastIndexOf(")");
            range = parseRange(express.substring(0, index + 1));
            startIndex = index + 1;
        }
        if (express.contains("]")) {
            int index = express.lastIndexOf("]");
            range = parseRange(express.substring(0, index + 1));
            startIndex = index + 1;
        }
        String variable = express.substring(startIndex);
        if (isValidString(variable)) {
            RangeObj rangeObj = new RangeObj();
            rangeObj.setRange(range);
            rangeObj.setObjectName(variable);
            return rangeObj;
        }

        throw new RuntimeException(String.format("表达式 %s有误", express));
    }

    public static boolean isValidString(String input) {
        String regex = "^(?!\\d)@?[a-zA-Z0-9\\u0080-\\uFFFF]+$";
        Pattern pattern = Pattern.compile(regex);
        // 进行匹配
        return pattern.matcher(input).matches();
    }

    public static Range parseRange(String express) {
        if (express.equals("")) {
            return Range.ONE;
        }
        String regex = "^([\\[\\(])(\\d+),(\\d+)?([\\]\\)])$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(express);

        if (matcher.matches()) {
            // 提取起始符号
            String startSymbol = matcher.group(1);
            // 提取第一个数字
            String firstNumber = matcher.group(2);
            Integer start = Integer.parseInt(firstNumber);
            // 提取第二个数字
            String secondNumber = matcher.group(3);
            Integer end = null;
            if (StringUtils.isNotBlank(secondNumber)) {
                end = Integer.parseInt(secondNumber);
            }
            // 提取结束符号
            String endSymbol = matcher.group(4);
            return new Range(start, end, "[".equals(startSymbol), "]".equals(endSymbol));
        } else if ("1".equals(express)) {
            return Range.ONE;
        } else {
            throw new RuntimeException("输入的字符串不符合区间格式");
        }
    }

    private void createRelationInstance(ConceptManage conceptManage, String line) {
        // 提取字符串
        FuncCall relation = readFuncCall(line);
        String relationName = relation.funcName;
        String[] elements = relation.paramExpress.split(",");
        Utils.createRelation2(conceptManage, relationName, elements);
    }

    private String removeComment(String line) {
        String[] lines = line.split("//");
        return lines[0].trim();
    }

    private static String[] split(String line) {
        return line.split("[ ,]+");
    }

    public static void main(String[] args) {
        {
            String input = "buildMap((location,weacher),(长治,阴天))";
            buildMap(null, input);
        }
        {
            String input = "conceptMerge((sourceObj,targetObj),(aaa,bb))";
            conceptMerge(null, input);
        }
        {
            String input = "buildMap((sourceObj1,sourceObj2,targetObj),((node2,node2,value),(node3,node3,value)))";
            //buildMap(null, input);
        }
        {
            String input = "buildEqualMap((sourceObj1,sourceObj2,targetObj),sourceObj1)";
            //buildEqualMap(null, input);
        }
        {
            String input = "buildConstMap((sourceObj1,sourceObj2,targetObj),constValue)";
            buildConstMap(null, input);
        }
        take(null, "take((node1,value),(node2,value),(node3,value),dest)");
    }

    public static class ScriptReader {

        String[] lines;

        int currentLine = 0;

        public ScriptReader(String script) {
            lines = script.split("\\n");
        }

        public boolean hasNext() {
            return currentLine < lines.length;
        }

        public String nextLine() {
            if (hasNext()) {
                return lines[currentLine++].trim();
            }
            throw new EndOfFileException();
        }

        public void goBack() {
            if (currentLine > 0) {
                currentLine--;
            }
        }

    }

}
